﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Consul;
using Hangfire;
using Hangfire.Redis;
using MicroContainers.AspCore.Consul;
using MicroContainers.AspCore.Consul.HealthCheck;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using RabbitMQ.Client;
using StackExchange.Redis;
using Swashbuckle.AspNetCore.Swagger;
using TimeTickService.Configs;
using TimeTickService.Extensions.HealthCheck;
using LogLevel = Microsoft.Extensions.Logging.LogLevel;

namespace TimeTickService
{
    public class Startup
    {
        public static ConnectionMultiplexer Redis;

        public Startup(IHostingEnvironment env)
        {
            var builder = new ConfigurationBuilder()
                .SetBasePath(env.ContentRootPath)
                .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
                .AddEnvironmentVariables();

            Configuration = builder.Build();

            Redis = ConnectionMultiplexer.Connect(Configuration["Redis"]);
        }

        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddMvc();
            services.AddHangfire(r => r.UseRedisStorage(Redis, options: new RedisStorageOptions { Db = 4 }));

            services.Configure<RabbitMqSetting>(Configuration.GetSection("RabbitMQ"));

            services.AddConsul(Configuration.GetSection("consulConfig"));

            services.AddSwaggerGen(options =>
            {
                options.SwaggerDoc("v1", new Info { Title = "定时器API", Version = "v1" });
            });
            var connectionFactory = new ConnectionFactory
            {
                HostName = Configuration["RabbitMQ:Host"],
                Port = int.Parse(Configuration.GetSection("RabbitMQ")["Port"]),
                UserName = Configuration["RabbitMQ:User"],
                Password = Configuration["RabbitMQ:Password"]
            };
            services.AddSingleton<IConnectionFactory>(f => connectionFactory)
                .AddSingleton<IRedisHelper>(f => new RedisHelper(Configuration["Redis"], 7, "ScheduleTask"))
                .AddMqHelper();

            services.AddHealthChecks(checks =>
            {
                checks.AddRabbitMQCheck("Trigger MQ", connectionFactory);
            });

        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IHostingEnvironment env, IApplicationLifetime lifetime, ILoggerFactory loggerFactory)
        {
            if (env.IsDevelopment())
            {
                loggerFactory.AddConsole(LogLevel.Debug);
                app.UseDeveloperExceptionPage();
            }

            app.UseMvc();
            app.UseHangfireServer();
            app.UseHangfireDashboard();
            app.UseSwagger();
            app.UseSwaggerUI(option =>
            {
                option.SwaggerEndpoint("/swagger/v1/swagger.json", "My API V1");
            });
            app.RegisterWithConsul(lifetime, new List<IHeathCheckConfig>()
            {
                new HttpHealthCheckConfig
                {
                    Url = Configuration["server:visible"]+"/hc",
                    Notes = "health check with http"
                }
            });
        }
    }
}
